using SocketIOClient;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Client = SocketIOClient.SocketIO;

public class NetworkManager : MonoBehaviour
{
    public static NetworkManager Instance { get; private set; }
    private Client client;
    private readonly string clientUrl = "http://localhost:3000";
    public string UserName;
    [SerializeField] private string clientId;
    public string ServerVersion;

    public void Awake()
    {
        if (Instance != null && Instance != this) Destroy(gameObject);
        else Instance = this;
    }

    public IEnumerator Initialize()
    {
        CreateClient();
        yield return client.ConnectAsync();
        yield return new WaitUntil(() => client.Connected);
        Login(UserName);
    }

    public void Login(string username)
    {
        UserName = username;
        StartCoroutine(ProcessLogin(UserName));
    }
    public event Action<string> OnLogin;
    public IEnumerator ProcessLogin(string username)
    {
        var t = client.EmitAsync("login", UserName);
        yield return new WaitUntil(() => t.IsCompleted);
        if (DepotManager.Instance) DepotManager.Instance.PullData();
        OnLogin?.Invoke(username);
    }


    async void OnDestroy()
    {
        if (client != null)
        {
            await client.DisconnectAsync();
            client.Dispose();
            client = null;
        }
    }

    public Client Client() { return client; }
    public string ClientId() { return clientId; }

    public event Action<SocketIOResponse> OnPlayersUpdate;
    public event Action<SocketIOResponse> OnObjectsUpdate;

    public event Action<SocketIOResponse> OnItemInfo;
    public event Action<SocketIOResponse> OnDepotData;
    private void CreateClient()
    {
        client = new Client(clientUrl);
        client.On("newId", response => { clientId = response.GetValue<string>(); });
        client.On("getVersion", response => { ServerVersion = response.GetValue<string>(); });

        client.On("playersUpdate", response => OnPlayersUpdate?.Invoke(response));
        client.On("objectsUpdate", response => OnObjectsUpdate?.Invoke(response));
        client.On("itemInfo:list", response => OnItemInfo?.Invoke(response));
        client.On("playerItems:data", response => OnDepotData?.Invoke(response));
    }
}